﻿using Dapper;
using Microsoft.Extensions.Configuration;
using MySqlConnector;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Threading.Tasks;

namespace Infrastructure
{
    public class DapperHelper : IDisposable
    {
        private readonly IDbConnection _db;
        private bool _disposed = false;

        // 通过构造函数注入配置
        public DapperHelper(IConfiguration configuration)
        {
            string connectionString = configuration.GetConnectionString("DB");
            _db = new MySqlConnection(connectionString);
            _db.Open();
        }

        // 查询单个对象
        public async Task<T> QuerySingleAsync<T>(string sql, object param = null)
        {
            return await _db.QuerySingleOrDefaultAsync<T>(sql, param);
        }

        // 查询列表
        public async Task<IEnumerable<T>> QueryAsync<T>(string sql, object param = null)
        {
            return await _db.QueryAsync<T>(sql, param);
        }

        // 执行非查询操作（增删改）
        public async Task<int> ExecuteAsync(string sql, object param = null)
        {
            return await _db.ExecuteAsync(sql, param);
        }

        // 事务执行
        public async Task<T> ExecuteInTransactionAsync<T>(Func<IDbConnection, IDbTransaction, Task<T>> action)
        {
            // 使用已打开的连接启动事务
            using var transaction = _db.BeginTransaction();
            try
            {
                var result = await action(_db, transaction);
                transaction.Commit();
                return result;
            }
            catch
            {
                transaction.Rollback();
                throw;
            }
        }

        // 实现 IDisposable 模式
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    // 正确关闭和释放连接
                    _db?.Close();
                    _db?.Dispose();
                }
                _disposed = true;
            }
        }
    }
}